package com.mvs.flyingbot;

import java.util.Iterator;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.ScreenAdapter;
import com.badlogic.gdx.Application.ApplicationType;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.graphics.g2d.Animation.PlayMode;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.Array;
import com.mvs.flyingbot.World.WorldListener;

public class GameScreen extends ScreenAdapter {

	static final int GAME_READY = 0;
	static final int GAME_RUNNING = 1;
	static final int GAME_PAUSED = 2;
	static final int GAME_LEVEL_END = 3;
	static final int GAME_OVER = 4;
	static final float SCREEN_WIDTH = 320;
	static final float SCREEN_HEIGHT = 480;
	final SillyBat game;
	OrthographicCamera uiCamera;

	int state;
	Vector3 touchPoint;
	World world;
	WorldListener worldListener;
	WorldRenderer renderer;
	Rectangle pauseBounds;
	Rectangle resumeBounds;
	Rectangle quitBounds;
	Rectangle backBounds;
	Rectangle playBounds;
	int lastScore;
	String scoreString;

	public GameScreen(final SillyBat gam) {
		this.game = gam;

		state = GAME_READY;

		uiCamera = new OrthographicCamera(SCREEN_WIDTH, SCREEN_HEIGHT);
		uiCamera.position.set(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, 0);
		
		worldListener = new WorldListener() {
			@Override
			public void jump() {
				Assets.playSound(Assets.jumpSound);
			}

			@Override
			public void highJump() {
				Assets.playSound(Assets.highJumpSound);
			}

			@Override
			public void hit() {
				Assets.playSound(Assets.hitSound);
			}
			//
			// @Override
			// public void coin () {
			// Assets.playSound(Assets.coinSound);
			// }
		};

		world = new World(worldListener);
		renderer = new WorldRenderer(game.batch, world);
		// pauseBounds = new Rectangle(320 - 64, 480 - 64, 64, 64);
		// resumeBounds = new Rectangle(160 - 96, 240, 192, 36);
		// quitBounds = new Rectangle(160 - 96, 240 - 36, 192, 36);
		backBounds = new Rectangle(200 - 50 / 2, 210 - 40 / 2, 50, 40);
		playBounds = new Rectangle(120 - 60 / 2, 210 - 40 / 2, 60, 40);
		touchPoint = new Vector3();
		lastScore = 0;
		scoreString = "SCORE: 0";
	}

	@Override
	public void render(float delta) {

		Gdx.gl.glClearColor(0, 0, 0.2f, 1);
		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

		updateWorld(delta);
		drawWorld();

	}

	private void updateReady() {
		if (Gdx.input.justTouched()) {
			state = GAME_RUNNING;
		}
	}

	private void updateRunning(float deltaTime) {

		ApplicationType appType = Gdx.app.getType();

		if (appType == ApplicationType.Android
				|| appType == ApplicationType.iOS) {
			if (Gdx.input.isTouched())
				world.update(deltaTime, Gdx.input.getAccelerometerX(), true);
			else
				world.update(deltaTime, Gdx.input.getAccelerometerX(), false);

		} else {
			float accel = 0;
			if (Gdx.input.isKeyPressed(Keys.DPAD_LEFT))
				accel = 4f;
			if (Gdx.input.isKeyPressed(Keys.DPAD_RIGHT))
				accel = -4f;
			if (Gdx.input.isTouched())

				world.update(deltaTime, accel, true);
			else
				world.update(deltaTime, accel, false);
		}

		if (world.score != lastScore) {
			lastScore = world.score;
			scoreString = "SCORE: " + lastScore;
		}

		if (world.state == World.WORLD_STATE_GAME_OVER) {
			state = GAME_OVER;
			// if (lastScore >= Settings.highscores[4])
			// scoreString = "NEW HIGHSCORE: " + lastScore;
			// else
			scoreString = "SCORE: " + lastScore;

		}

	}

	private void updateWorld(float deltaTime) {
		// if (deltaTime > 0.1f) deltaTime = 0.1f;
		// GameStateTime += Gdx.graphics.getDeltaTime();
		switch (state) {
		case GAME_READY:
			updateReady();
			break;
		case GAME_RUNNING:
			updateRunning(deltaTime);
			break;
		// case GAME_PAUSED:
		// updatePaused();
		// break;
		// case GAME_LEVEL_END:
		// updateLevelEnd();
		// break;
		case GAME_OVER:
			updateGameOver();
			break;
		}

	}

	private void drawWorld() {
		
		GL20 gl = Gdx.gl;
		gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
		renderer.render();
		uiCamera.update();

		game.batch.setProjectionMatrix(uiCamera.combined);
		game.batch.enableBlending();
		game.batch.begin();
		
		switch (state) {
		case GAME_READY:
			presentReady();
			break;
		case GAME_RUNNING:
			presentRunning();
			break;
		// case GAME_PAUSED:
		// presentPaused();
		// break;
		// case GAME_LEVEL_END:
		// presentLevelEnd();
		// break;
		case GAME_OVER:
			presentGameOver();
			break;
		}
		game.batch.end();

	}

	private void presentRunning() {
		Assets.scorefont.setScale(0.6f);
		Assets.scorefont.draw(game.batch, "" + lastScore, 260, 470);

	}

	private void presentReady() {

		game.batch.draw(Assets.ready, 160 - 170 / 2, 300 - 40 / 2, 170, 40);
	}

	@Override
	public void pause() {
		if (state == GAME_RUNNING)
			state = GAME_PAUSED;
	}

	private void updateGameOver() {

		if (Gdx.input.justTouched()) {
			uiCamera.unproject(touchPoint.set(Gdx.input.getX(),
					Gdx.input.getY(), 0));

			if (backBounds.contains(touchPoint.x, touchPoint.y)) {
				Assets.playSound(Assets.clickSound);
				game.setScreen(new MainMenuScreen(game));
				}

			if (playBounds.contains(touchPoint.x, touchPoint.y)) {
				Assets.playSound(Assets.clickSound);
				game.setScreen(new GameScreen(game));
				}

		}
		
	}

	private void presentGameOver() {
		game.batch.draw(Assets.gameOver, 160 - 230 / 2, 300 - 40 / 2, 230, 40);
		game.batch.draw(Assets.backbutton, 200 - 50 / 2, 210 - 40 / 2, 50, 40);
		game.batch.draw(Assets.playbutton, 120 - 60 / 2, 210 - 40 / 2, 60, 40);
		Assets.font.setScale(0.5f);
		Assets.font.draw(game.batch, "Your Score: " + lastScore, 80, 270);
		Assets.font.draw(game.batch, "Best Score: 100", 80, 250);

	}

}
